#pragma once
#ifndef __SCRIPT__EDITOR__SOLUTION__HH__
#define __SCRIPT__EDITOR__SOLUTION__HH__

#include "ScriptEditorPrereqs.h"
#include "ScriptEditorSolutionSettings.h"
#include "LitScriptStream.h"

namespace Lit
{
	class FilePath;
	namespace Editor
	{
		class ScriptSolution : public QObject, Ogre::FrameListener
		{
			Q_OBJECT
		public:
			typedef std::vector<ScriptSolutionItemPtr> ScriptList;

			bool hasItem( const ScriptSolutionItem::WidgetPtr& win ) const;
			bool hasItem( const ScriptSolutionItem::NodePtr& nod ) const;
			bool hasItem( const ScriptSolutionItemPtr& itm ) const;
			
			ScriptSolutionItemPtr findItem( const ScriptSolutionItem::WidgetPtr& win ) const;
			ScriptSolutionItemPtr findItem( const ScriptSolutionItem::NodePtr& nod ) const;
			ScriptSolutionItemPtr findItem( const ScriptSolutionItemPtr& itm ) const;
			
			ScriptSolutionItemPtr addItem( ScriptSolutionItem::NodePtr node, ScriptSolutionItem::WidgetPtr win );
			bool removeItem( ScriptSolutionItemPtr &item );

			void clearItems();

		protected:
			ScriptCompilerPtr					mCompiler;		
			ScriptTabWidgetPtr					mTabs;
			ScriptSolutionTree*					mTree;
			FilePath							mSavePath;
			ScriptList							mScripts;
			std::string							mName;
			std::string							mEntryPoint;
			std::string							mRenderEntryPoint;
			bool								mCreated;
			RefPtr<Instance>					mInstance;
			ScriptSolutionSettings				mSettingsDlg;
			ScriptModulePtr						mRenderModule;

		public:
			ScriptSolution( ScriptSolutionTree * tree, ScriptTabWidgetPtr , InstancePtr inst );
			~ScriptSolution();
			
			FilePath getSolutionDir() const{ return ScriptUserPath() + "/" + mName; }

			const std::string& getEntryPoint() const{ return mEntryPoint; }
			void setEntryPoint(const std::string&p) { mEntryPoint = p; }

			const std::string& getRenderEntryPoint() const{ return mRenderEntryPoint; }
			void setRenderEntryPoint(const std::string& p) { mRenderEntryPoint = p; }
			
			void _importSol( const FilePath &p );
			void _exportSol( const FilePath &p );
			
			ScriptSolutionItemPtr getCurrentScript() const;

			void newSolution();
			void openSolution();
			void saveSolution( bool as = false );
			bool closeSolution();
			
			void showSettings();
			
			void buildError( ScriptModulePtr mod, const std::string &err );
			void buildSuccess( ScriptModulePtr mod );

			void compile();
			void compileByteCode();
			void run();
						
			bool frameRenderingQueued( const Ogre::FrameEvent &evt );

			std::string generateScriptName();

			const std::string &getName() const{ return mName; }

			const ScriptCompilerPtr& getCompiler() const;
			const ScriptTabWidgetPtr& getTabs() const;

			const ScriptList&	getScripts() const;
			ScriptList&			getScripts();

			ScriptList			getRenderScripts() const;

			ScriptSolutionTree* getTreeWidget();
			const FilePath& getSavePath() const;
			bool isSavePathDefined() const;

			bool isCreated() const;
			void prepareUi( const std::string &name );
			
			
			bool hasScript( const std::string &name ) const;
			bool hasScript( const ScriptSolutionItemPtr &itm ) const;
			bool hasScript( const ScriptSolutionItem::NodePtr &node ) const;
			bool hasScript( const ScriptSolutionItem::WidgetPtr &widget ) const;

			ScriptSolutionItemPtr findScript( const std::string &name ) const;
			ScriptSolutionItemPtr findScript( const ScriptSolutionItem::NodePtr &node ) const;
			ScriptSolutionItemPtr findScript( const ScriptSolutionItem::WidgetPtr &widget ) const;

			ScriptSolutionItemPtr openScript( const std::string &path = "" );
			ScriptSolutionItemPtr createScript( const std::string &base_name = "", size_t flags = ScriptSolutionItem::ItemIsCompilable );
			
		protected slots:
			void modifiedStateChanged(ScriptEditorWidget *, bool);	

			void openScriptEditor( ScriptSolutionItemPtr item );
			void closeScriptEditor( ScriptSolutionItemPtr item );
			void showScriptContextMenu( ScriptSolutionItemPtr item );

			void tabCloseRequested ( int index );
		};
	};
};

#endif
